package _Pan3D.role
{
	import _Pan3D.base.MeshData;
	import _Pan3D.base.ObjectTri;
	import _Pan3D.base.ObjectUv;
	import _Pan3D.base.ObjectWeight;
	import _Pan3D.core.CountObject;
	import _Pan3D.display3D.analysis.AnalysisServer;
	import _Pan3D.display3D.analysis.ObjAnalysis;
	import _Pan3D.load.LoadInfo;
	import _Pan3D.load.LoadManager;
	
	import flash.display3D.Context3D;

	public class MeshDataManager
	{
		private var _meshDic:Object = new Object;//key:url,value:countobject
		private var _loadFunDic:Object = new Object;
		private var _context:Context3D;
		
		private static var instance:MeshDataManager;
		public function MeshDataManager()
		{
			
		}
		public static function getInstance():MeshDataManager{
			if(!instance){
				instance = new MeshDataManager;
			}
			return instance;
		}
		public function init(context:Context3D):void{
			this._context = context;
		}
		public function addMesh(url:String,fun:Function,info:Object):void{
			if(_meshDic.hasOwnProperty(url)){
				fun(_meshDic[url].obj,info);
				_meshDic[url].num++;
			}else{
				if(!_loadFunDic.hasOwnProperty(url)){
					_loadFunDic[url] = new Array;
					var loaderinfo:LoadInfo = new LoadInfo(url,LoadInfo.XML,onMeshLoad,false,url);
					LoadManager.getInstance().addSingleLoad(loaderinfo);
				}
				_loadFunDic[url].push({"fun":fun,"info":info});
			}
		}
		
		private function onMeshLoad(str:String,url:String):void{
			var meshData:MeshData = AnalysisServer.getInstance().analysisMesh(str);//new Md5Analysis().addMesh(str,1);
			processForAgal(meshData);
			
			var countobj:CountObject = new CountObject;
			countobj.obj = meshData;
			
			var ary:Array = _loadFunDic[url];
			for each(var obj:Object in ary){
				obj.fun(meshData,obj.info)
				countobj.num++;
			}
			delete _loadFunDic[url];
			
			_meshDic[url] = countobj;
			
			//_meshDic[place] = meshData;
		}
		
		private function processForAgal(meshData:MeshData):void{
			var uvItem:Vector.<ObjectUv> = meshData.uvItem;
			var weightItem:Vector.<ObjectWeight> = meshData.weightItem;
			var triItem:Vector.<ObjectTri> = meshData.triItem;
			
			var uvArray:Array=new Array();
			var ary:Array = [[],[],[],[]];
			var boneWeightAry:Array = new Array;
			var bonetIDAry:Array = new Array;
			var indexAry:Array = new Array;
			
			var skipNum:int;
			var beginIndex:int;
			var allNum:int;
			
			var boneUseAry:Array = new Array;
			
			for(var i:int = 0;i<uvItem.length;i++){
				beginIndex = uvItem[i].a;
				allNum = uvItem[i].b;
				for(skipNum = 0;skipNum<4;skipNum++){
					if(skipNum<allNum){
						boneUseAry.push((weightItem[beginIndex+skipNum].boneId));
					}else{
						boneUseAry.push(0);
					}
				}
			}
			
			boneUseAry = getboneNum(boneUseAry);
			
			for(i = 0;i<uvItem.length;i++){
				beginIndex = uvItem[i].a;
				allNum = uvItem[i].b;
				for(skipNum = 0;skipNum<4;skipNum++){
					if(skipNum<allNum){
						ary[skipNum].push(weightItem[beginIndex+skipNum].x,weightItem[beginIndex+skipNum].y,weightItem[beginIndex+skipNum].z);
						bonetIDAry.push(12 + boneUseAry.indexOf((weightItem[beginIndex+skipNum].boneId))*4);
						boneWeightAry.push(weightItem[beginIndex+skipNum].w);
					}else{
						ary[skipNum].push(0,0,0);
						bonetIDAry.push(12 + boneUseAry.indexOf(0));
						boneWeightAry.push(0);
					}
				}
				uvArray.push(uvItem[i].x);
				uvArray.push(uvItem[i].y);
			}
			
			meshData.boneNewIDAry = boneUseAry;
			
			for(i=0;i<triItem.length;i++){
				indexAry.push(triItem[i].t0,triItem[i].t1,triItem[i].t2);
			}
			uplodToGpu(meshData,uvArray,ary,
				boneWeightAry,bonetIDAry,indexAry);
			//getboneNum(bonetIDAry);
		}
		private function getboneNum(ary:Array):Array{
			var numAry:Array = new Array;
			for(var i:int;i<ary.length;i++){
				if(numAry.indexOf(ary[i]) == -1){
					numAry.push(ary[i]);
				}
			}
			//trace(numAry.length);
			return numAry;
		}
		private function uplodToGpu(meshData:MeshData,uvArray:Array,ary:Array,
									boneWeightAry:Array,bonetIDAry:Array,indexAry:Array):void{
			meshData.uvBuffer = this._context.createVertexBuffer(uvArray.length/2,2);
			meshData.uvBuffer.uploadFromVector(Vector.<Number>(uvArray),0,uvArray.length/2);
			
			meshData.vertexBuffer1 = this._context.createVertexBuffer(ary[0].length/3,3);
			meshData.vertexBuffer1.uploadFromVector(Vector.<Number>(ary[0]),0,ary[0].length/3);
			
			meshData.vertexBuffer2 = this._context.createVertexBuffer(ary[1].length/3,3);
			meshData.vertexBuffer2.uploadFromVector(Vector.<Number>(ary[1]),0,ary[1].length/3);
			
			meshData.vertexBuffer3 = this._context.createVertexBuffer(ary[2].length/3,3);
			meshData.vertexBuffer3.uploadFromVector(Vector.<Number>(ary[2]),0,ary[2].length/3);
			
			meshData.vertexBuffer4 = this._context.createVertexBuffer(ary[3].length/3,3);
			meshData.vertexBuffer4.uploadFromVector(Vector.<Number>(ary[3]),0,ary[3].length/3);
			
			meshData.boneWeightBuffer = this._context.createVertexBuffer(boneWeightAry.length/4,4);
			meshData.boneWeightBuffer.uploadFromVector(Vector.<Number>(boneWeightAry),0,boneWeightAry.length/4);
			
			meshData.boneIdBuffer = this._context.createVertexBuffer(bonetIDAry.length/4,4);
			meshData.boneIdBuffer.uploadFromVector(Vector.<Number>(bonetIDAry),0,bonetIDAry.length/4);
			
			meshData.indexBuffer = this._context.createIndexBuffer(indexAry.length);
			meshData.indexBuffer.uploadFromVector(Vector.<uint>(indexAry),0,indexAry.length);
			
			//meshData.texture= this._context.createTexture(meshData.uvBitmapdata.width, meshData.uvBitmapdata.height, Context3DTextureFormat.BGRA, true);
			//meshData.texture.uploadFromBitmapData(meshData.uvBitmapdata);
			
		}
		
	}
}